package com.mti.zhpt.shared.websocket;

import com.alibaba.fastjson.JSON;
import com.mti.zhpt.dao.CommandCustomMapper;
import com.mti.zhpt.dao.EventDetailsMapper;
import com.mti.zhpt.dao.EventDetailsTimerMapper;
import com.mti.zhpt.model.websocket.WSCustomEntity;
import com.mti.zhpt.shared.classHelper.TaskHandler;
import com.mti.zhpt.utils.Constant;
import com.mti.zhpt.utils.DateUtil;
import com.mti.zhpt.shared.websocket.encoder.ServerEncoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @Description: 精准指挥--执行
 * 预案指挥-执行
 * @Author: zhaopf@mti-sh.cn
 * @Date: 2019/4/23 11:53
 * @ServerEndpoint中不能用
 * @Autowired
 * @Resource
 */
@Slf4j
@ServerEndpoint(value = "/webSocket/custom/{userId}", encoders = {ServerEncoder.class})
@Component
public class WSCustomServer {
    private static CopyOnWriteArraySet<WSCustomServer> webSocketSet = new CopyOnWriteArraySet<WSCustomServer>();
    private Session session;
    private String userId;
//    TaskHandler taskHandler = SpringContext.getBean(TaskHandler.class);

    public static TaskHandler taskHandler;
    public static CommandCustomMapper commandCustomMapper;
    public static EventDetailsTimerMapper eventDetailsTimerMapper;
    public static EventDetailsMapper eventDetailsMapper;

    @Autowired
    private void setTaskHandler(TaskHandler taskHandler) {
        WSCustomServer.taskHandler = taskHandler;
    }

    @Autowired
    private void setCommandCustomMapper(CommandCustomMapper commandCustomMapper) {
        WSCustomServer.commandCustomMapper = commandCustomMapper;
    }

    @Autowired
    private void setCommandCustomMapper(EventDetailsTimerMapper eventDetailsTimerMapper) {
        WSCustomServer.eventDetailsTimerMapper = eventDetailsTimerMapper;
    }

    @Autowired
    private void setEventDetailsMapper(EventDetailsMapper eventDetailsMapper) {
        WSCustomServer.eventDetailsMapper = eventDetailsMapper;
    }

    // 使用map来收集session，key为name，value为用户
    // concurrentMap的key不存在时报错，不是返回null
    private static final Map<String, Set<Session>> nameMap = new ConcurrentHashMap<String, Set<Session>>();
    List<WSCustomEntity> wsCustomEntity;

    @OnOpen
    public void connect(@PathParam("userId") String userId, Session session) throws Exception {
        this.userId = userId;
        // 将session按照用户来存储
        if (!nameMap.containsKey(userId)) {
            // 用户不存在时
            // 添加用户
            Set<Session> user = new HashSet<>();
            // 添加用户
            user.add(session);
            nameMap.put(userId, user);

            webSocketSet.add(this);
            this.session = session;

        } else {
            // 用户已存在
            nameMap.get(userId).add(session);

        }
        log.info("新连接：{}", userId);

    }

    @OnClose
    public void disConnect(@PathParam("userId") String userId, Session session) {
        webSocketSet.remove(this);
        try {
            /**
             * 用户，只有一个连接
             * 移除该用户
             * 有多个连接，移除该连接
             */
            if (!CollectionUtils.isEmpty(nameMap) && !CollectionUtils.isEmpty(nameMap.get(userId))) {
                Set<Session> sessions = nameMap.get(userId);
                if (sessions.size() == 1) {
                    nameMap.remove(userId);
                }
                if (sessions.size() > 1) {
                    sessions.remove(session);
                }

            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        log.info("连接：{} 关闭", userId);

    }

    @OnMessage
    public void receiveMsg(@PathParam("userId") String userId, String msg, Session session) throws Exception {

        try {
            log.info("收到用户{}的消息:{}", userId, msg);

            wsCustomEntity = JSON.parseArray(msg, WSCustomEntity.class);
            if (CollectionUtils.isEmpty(wsCustomEntity)) {
                return;
            }

            //commandCustomMapper.updateStatus(wsCustomEntity);
            List<Map<String, Object>> listMap = new ArrayList<>();
            Map<String, Object> map = new HashMap<>();
            for (WSCustomEntity entity : wsCustomEntity) {
                Map<String, Object> detailsEntity = eventDetailsMapper.queryDetails(entity.getEventId());
                eventDetailsTimerMapper.insertTimer(entity);
                map.put("id", entity.getTimerId());
                map.put("msgType", Constant.MSG_ORDER);
                map.put("title", detailsEntity.get("address"));
                map.put("content", detailsEntity.get("content"));
                map.put("orderType", detailsEntity.get("case_type"));
                map.put("createTime", DateUtil.formatDate((Date) detailsEntity.get("create_time"), "datetime"));
                listMap.add(map);
            }


            String AppResult = JSON.toJSONString(listMap);


        } catch (Exception e) {
            log.error("用户id为：{}的连接发送错误", this.userId);
            log.error(e.getMessage());
        }
    }

    // 连接错误时执行
    @OnError
    public void onError(Session session, Throwable error) {
        log.info("用户id为：{}的连接发送错误", this.userId);
        error.printStackTrace();
    }

    public void sendObject(Object data) {
        log.debug("sendObject");
        try {


            this.session.getBasicRemote().sendObject(data);
        } catch (IOException | EncodeException e) {
            log.debug("发送消息出现错误");
            log.error(e.getMessage());
        }
    }

    public static void sendInfo(Object data, String user) throws IOException {

        try {
        	if(nameMap.containsKey(user)) {
            for (Session session : nameMap.get(user)) {
                session.getBasicRemote().sendObject(data);
            }
        	}
        } catch (Exception e) {
            log.error(e.getMessage());
            log.error("错误信息" + e.getMessage());
        }
//		log.error(Integer.toString(webSocketSet.size()));
//		for (WSCustomServer item : webSocketSet) {
//			log.error(item.userId);
//			if(item.userId.equals(user))
//				item.sendObject(data);
//		}
    }

}